package com.oa.admin.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.joneying.common.annotation.CommonService;
import com.joneying.common.web.response.Resp;
import com.oa.admin.dto.DormAddDTO;
import com.oa.admin.dto.DormApprovalDTO;
import com.oa.admin.dto.DormConditionDTO;
import com.oa.admin.entity.CheckInList;
import com.oa.admin.entity.Dorm;
import com.oa.admin.exportvo.DormApplicationExportVO;
import com.oa.admin.mapper.CheckInListMapper;
import com.oa.admin.mapper.DormMapper;
import com.oa.admin.service.ICheckInListService;
import com.oa.admin.service.IDormService;
import com.oa.admin.vo.ApprovalCheckVO;
import com.oa.admin.vo.DormDetailsVO;
import com.oa.admin.vo.DormListVO;
import com.oa.core.PageResult;
import com.oa.core.enumm.CodeEnum;
import com.oa.core.enumm.ProcessDefineEnum;
import com.oa.core.exception.BusinessException;
import com.oa.core.exception.DataIsEmptyException;
import com.oa.core.utils.DateUtil;
import com.oa.core.utils.ExcelUtil;
import com.oa.pm.entity.Organization;
import com.oa.pm.service.IOrganizationService;
import com.oa.system.dto.ApplyApprovalAddDTO;
import com.oa.system.dto.ApprovalDTO;
import com.oa.system.entity.*;
import com.oa.system.service.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletResponse;
import java.util.*;

import static com.oa.core.utils.Validate.validate;

/**
 * <p>
 * 宿舍申请表 服务实现类
 * </p>
 *
 * @author syb123
 * @since 2019-01-22
 */
@Service
public class DormServiceImpl extends ServiceImpl<DormMapper, Dorm> implements IDormService {

    @Autowired
    private DormMapper dormMapper;

    @Autowired
    private IApplyApprovalService applyApprovalService;


    @Autowired
    private IUserService userService;

    @Autowired
    private IOrganizationService organizationService;

    @Autowired
    private ICheckInListService checkInListService;

    @Autowired
    HttpServletResponse response;

    @Override
    @CommonService
    public PageResult<Dorm> findList(Integer pageNum, Integer pageSize) {
        if (pageNum == null) {
            List<Dorm> list = dormMapper.findList();
            return new PageResult<>(list);
        } else {
            // 当前页，总条数 构造 page 对象
            Page<Dorm> page = new Page<>(pageNum, pageSize);
            //查询
            List<Dorm> list = dormMapper.findList(page);
            return new PageResult<>(list);
        }
    }

    /**
     * 根据id查询
     */
    @Override
    @CommonService
    public Dorm findDormById(String id) {
        return dormMapper.findById(id);
    }

    /**
     * 提交宿舍申请
     *
     * @param dormAddDTO
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    @CommonService
    public Resp addDorm(String userId, DormAddDTO dormAddDTO) throws BusinessException, DataIsEmptyException {
        User user = userService.selectById(userId);
        Organization organization = organizationService.selectById(user.getDepartmentId());
        dormAddDTO.setProposer(userId);
        dormAddDTO.setDepartment(organization.getId());
        CheckDormParam(dormAddDTO);

        Dorm dorm = new Dorm();
        BeanUtils.copyProperties(dormAddDTO, dorm);
        dorm.setCrteateTime(new Date());
        if(insert(dorm)){
            ApplyApprovalAddDTO applyApprovalAddDTO = new ApplyApprovalAddDTO();
            applyApprovalAddDTO.setApplyId(dorm.getId());
            applyApprovalAddDTO.setApprovalProcessId(ProcessDefineEnum.DORM_ROOM.getId());
            applyApprovalAddDTO.setApplyApprovalName(user.getName() + ProcessDefineEnum.DORM_ROOM.getText());
            applyApprovalAddDTO.setApprovalUserId(user.getId());
            return applyApprovalService.addApproval(applyApprovalAddDTO);
        }
        throw new BusinessException("添加宿舍申请失败!");
    }

    /**
     * 根据条件查询宿舍申请
     *
     * @param dormConditionDTO
     * @return
     */
    @Override
    @CommonService
    public PageResult<DormListVO> findDormListByCondition(DormConditionDTO dormConditionDTO) {
        Page page = dormConditionDTO.getPage();
        return new PageResult<>(dormMapper.findDormListByCondition(page, dormConditionDTO), page.getPages());
    }

    /**
     * 根据id查询宿舍申请详情
     *
     * @param id
     * @return
     */
    @Override
    @CommonService
    public Resp findDormDetailsById(String id) {
        return new Resp<DormDetailsVO>().success(dormMapper.findDormListDetails(id));
    }

    /**
     * 宿舍申请审批(审批后)
     *
     * @param dormApprovalDTO
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    @CommonService
    public Resp dormApproval(DormApprovalDTO dormApprovalDTO) throws BusinessException, DataIsEmptyException {

        CheckDormApprovalDTOParam(dormApprovalDTO);

        ApprovalDTO approvalDTO = new ApprovalDTO();
        approvalDTO.setId(Long.valueOf(dormApprovalDTO.getApplyApprovalId()));
        approvalDTO.setUserId("1");
        approvalDTO.setStatus(dormApprovalDTO.getStatus());

        return applyApprovalService.audit(approvalDTO, x -> {
            Dorm dorm = new Dorm();
            BeanUtils.copyProperties(dormApprovalDTO, dorm);
            if(updateById(dorm)){
                List<CheckInList> checkInLists = new ArrayList<>();
                dormApprovalDTO.getCheckInListAddDTOList().forEach(d -> {
                    CheckInList checkInList = new CheckInList();
                    BeanUtils.copyProperties(d, checkInList);
                    checkInList.setDormId(dorm.getId());
                    checkInLists.add(checkInList);
                });
                checkInListService.insertBatch(checkInLists);
            }
        });
    }

    /**
     * 导出宿舍申请列表
     *
     * @return
     */
    @Override
    @CommonService
    public Resp exportDormApplicationList() throws BusinessException {

        List<DormApplicationExportVO> dormApplicationExportVOList = dormMapper.findDormApplicationAll();

        String[] rowName = {"申请时间", "申请人", "部门", "申请入住日期", "安排入住日期", "审批状态"};

        try {
            ExcelUtil.downloadExcel("宿舍申请表" + DateUtil.getDayMonth(), rowName, dormApplicationExportVOList, "宿舍申请表" + DateUtil.getDayMonth() + ".xls", response);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException("导出宿舍申请excel表格失败!");
        }

        return new Resp<>().success("导出宿舍申请excel表格成功!");
    }


    /**
     * 参数校验
     *
     * @param
     */
    public void CheckDormApprovalDTOParam(DormApprovalDTO dormApprovalDTO) throws BusinessException {
        if (!StringUtils.isEmpty(dormApprovalDTO)) {
            List<String> validate = validate(dormApprovalDTO);
            if (CollUtil.isNotEmpty(validate)) {
                throw new BusinessException(CodeEnum.PARAMETERS_OF_THE_ABNORMAL.getCode(), validate.toString());
            }
        }
    }


    /**
     * 参数校验
     *
     * @param
     */
    public void CheckDormParam(DormAddDTO dormAddDTO) throws BusinessException {
        if (!StringUtils.isEmpty(dormAddDTO)) {
            List<String> validate = validate(dormAddDTO);
            if (CollUtil.isNotEmpty(validate)) {
                throw new BusinessException(CodeEnum.PARAMETERS_OF_THE_ABNORMAL.getCode(), validate.toString());
            }
        }
    }


    /**
     * 参数校验
     *
     * @param
     */
    public void CheckDormConditionDTOParam(DormConditionDTO dormConditionDTO) throws BusinessException {
        if (!StringUtils.isEmpty(dormConditionDTO)) {
            List<String> validate = validate(dormConditionDTO);
            if (CollUtil.isNotEmpty(validate)) {
                throw new BusinessException(CodeEnum.PARAMETERS_OF_THE_ABNORMAL.getCode(), validate.toString());
            }
        }
    }
}
